package com.jia.sign.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jia.constant.RedisConstant;
import com.jia.sign.constant.SignRedisConstant;
import com.jia.sign.entity.Sign;
import com.jia.sign.mapper.SignMapper;
import com.jia.sign.service.SignService;
import com.jia.sms.holder.UserHolder;
import org.springframework.data.redis.connection.BitFieldSubCommands;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * (Sign)表服务实现类
 *
 * @author makejava
 * @since 2024-10-12 21:29:22
 */
@Service("signService")
public class SignServiceImpl extends ServiceImpl<SignMapper, Sign> implements SignService {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    public static final String SIGN_REDIS_PREFIX = RedisConstant.PROJECT_REDIS_PREFIX +
            SignRedisConstant.SIGN_PREFIX;

    @Override
    public Boolean signMonth() {
        // 获取当前登录用户
        Long userId = UserHolder.getUser().getId();
        // 获取当前日期
        LocalDate now = LocalDate.now();
        String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
        String key = SIGN_REDIS_PREFIX + userId + keySuffix;
        // 获取今天是本月的第几天
        int dayOfMonth = now.getDayOfMonth();
        stringRedisTemplate.opsForValue().setBit(key, dayOfMonth - 1, true);
        return true;
    }

    @Override
    public Integer countSign() {
        // 获取当前登录用户
        Long userId = UserHolder.getUser().getId();
        LocalDate now = LocalDate.now();
        String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
        String key = SIGN_REDIS_PREFIX + userId + keySuffix;
        // 获取今天是本月的第几天
        int dayOfMonth = now.getDayOfMonth();
        // 无符号 使用当前时间来截取
        List<Long> longs = stringRedisTemplate.opsForValue().bitField(
                key, BitFieldSubCommands.create()
                        .get(BitFieldSubCommands.BitFieldType.unsigned(dayOfMonth)).valueAt(0)
        );

        if (longs == null || longs.isEmpty()) {
            return 0;
        }
        // 只会有一个结果 因为只有get一个子命令
        Long i = longs.get(0);
        if (i == 0) {
            return 0;
        }
        int count = 0;
        while ((i & 1) != 0) {
            count++;
            i >>>= 1;
        }
        return count;
    }

}
